﻿using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Linq;
using System.Security.Cryptography;
using System.Net.Http;
using Microsoft.Extensions.DependencyInjection;
using System.Runtime.InteropServices;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Net;
using System.Management;

namespace Utils
{
	
	public class CommonTools
	{
		/// <summary>
		/// 获取实例对象
		/// </summary>
		/// <typeparam name="T">对象类型</typeparam>
		/// <param name="dllname">程序集名称</param>
		/// <returns></returns>
		public static T GetInstance<T>(string dllname)
		{
			try
			{
				var asm = Assembly.LoadFile(dllname);
				var ts = asm.GetTypes();
				Type t = typeof(T);
				foreach (var t1 in ts)
				{
					if (t1.BaseType == typeof(T))
					{
						return (T)Activator.CreateInstance(t1);
					}
				}
			}
			catch(Exception ex)
			{

			}

			return default(T);
		}
		/// <summary>
		/// 获取单实例对象
		/// </summary>
		/// <typeparam name="T">对象类型</typeparam>
		/// <param name="dllname">程序集名称</param>
		/// <returns></returns>
		public static T GetSingletonInstance<T>(string dllname)
		{
			if (Singleton<T>.Instance == null)
			{
				Singleton<T>.Instance = GetInstance<T>(dllname);
			}
			return Singleton<T>.Instance;
		}

		#region 配置文件相关
		private static string _currentDir;//当前路径
		/// <summary>
		/// 当前路径GET属性
		/// </summary>
		public static string CurrentDir
		{
			get
			{
				if (string.IsNullOrEmpty(_currentDir))
				{
					var currentAssembly = Assembly.GetExecutingAssembly();
					_currentDir = Path.GetDirectoryName(currentAssembly.Location);
				}
				return _currentDir;
			}
		}
		/// <summary>
		/// 获取配置文件
		/// </summary>
		/// <returns>创建对象</returns>
		public static IConfigurationRoot GetJsonConfig()
		{
			string cfgDir = Path.Combine(CommonTools.CurrentDir, "config");
			var configBu = new ConfigurationBuilder()
				.SetBasePath(cfgDir);
			var dir = new DirectoryInfo(cfgDir);
			var jsonFiles = dir.GetFiles("*.json").Select(finfo => finfo.Name);
			foreach (var file in jsonFiles)
			{
				configBu.AddJsonFile(file, optional: false, reloadOnChange: true);
			}
			return configBu.Build();
		}
		/// <summary>
		/// 获取配置文件的单实例
		/// </summary>
		public static IConfiguration Config
		{
			get
			{
				if (Singleton<IConfigurationRoot>.Instance == null)
				{
					Singleton<IConfigurationRoot>.Instance = GetJsonConfig();
				}
				return Singleton<IConfigurationRoot>.Instance;
			}
		}
		/// <summary>
		/// 获取配置文件项的VALUE
		/// </summary>
		/// <typeparam name="T">对象类型</typeparam>
		/// <param name="key">节点key</param>
		/// <returns></returns>
		public static T GetConfigValue<T>(string key)
		{
			return Config.GetSection(key).Get<T>();
		}
		#endregion

		/// <summary>
		/// 数据MD5加密
		/// </summary>
		/// <param name="source">需要加密的数据</param>
		/// <returns>加密的字符串</returns>
		public static string MD5(string source)
		{
			MD5 md5 = System.Security.Cryptography.MD5.Create();
			string result = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(source))).Replace("-", null);
			return result;
		}
		/// <summary>
		/// 注册服务
		/// </summary>
		public static IHttpClientFactory HttpClientFactory
		{
			get
			{
				if (Singleton<IHttpClientFactory>.Instance == null)
				{
					IServiceCollection services = new ServiceCollection();
					services.AddHttpClient("ignoreSSL")
					.ConfigurePrimaryHttpMessageHandler(() =>
					{
						return new HttpClientHandler
						{
							ServerCertificateCustomValidationCallback = (m, crt, chn, e) => true
						};
					});
					services.AddHttpClient();
					IServiceProvider provider = services.BuildServiceProvider();
					Singleton<IHttpClientFactory>.Instance = provider.GetService<IHttpClientFactory>();
				}
				return Singleton<IHttpClientFactory>.Instance;
			}
		}

		public static string GetHostName(string ipStr)
		{

			string hostName = string.Empty;
			try
			{
				System.Net.IPAddress ip = System.Net.IPAddress.Parse(ipStr);
				System.Net.IPHostEntry host = System.Net.Dns.GetHostEntry(ip);
				hostName = host.HostName;
			}
			catch
			{ }
			return hostName;
		}

		[DllImport("Iphlpapi.dll")]
		static extern int SendARP(Int32 DestIP, Int32 SrcIP, ref Int64 MacAddr, ref Int32 PhyAddrLen);
		[DllImport("Ws2_32.dll")]
		static extern Int32 inet_addr(string ipaddr);
		
		/// <summary>
		/// 
		/// </summary>
		/// <param name="内网ip"></param>
		/// <returns>mac地址</returns>
		public static string GetMacByIp(string 内网ip)
		{
			StringBuilder macAddress = new StringBuilder();
			try
			{
				Int32 remote = inet_addr(内网ip);
				Int64 macInfo = new Int64();
				Int32 length = 6;
				SendARP(remote, 0, ref macInfo, ref length);
				string temp = Convert.ToString(macInfo, 16).PadLeft(12, '0').ToUpper();
				int x = 12;
				for (int i = 0; i < 6; i++)
				{
					if (i == 5)
					{
						macAddress.Append(temp.Substring(x - 2, 2));
					}
					else
					{
						macAddress.Append(temp.Substring(x - 2, 2) + "-");
					}
					x -= 2;
				}
				return macAddress.ToString();
			}
			catch
			{
				return macAddress.ToString();
			}
		}

		public static string GetLocalIp()
		{			
			string localIp = NetworkInterface.GetAllNetworkInterfaces()
				.Select(p => p.GetIPProperties())
				.SelectMany(p => p.UnicastAddresses)
				.FirstOrDefault(p => p.Address.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(p.Address))?.Address.ToString();
			return localIp;
		}

		public static string GetLocalMac() 
		{
			try
			{
				string mac = "";
				ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
				ManagementObjectCollection Moc = mc.GetInstances();
				foreach (ManagementObject mo in Moc)
					if (mo["IPEnabled"].ToString() == "True")
					{
						mac = mo["MacAddress"].ToString();
						break;
					}
				Moc = null;
				mc = null;
				return mac;
			}
			catch (Exception e)
			{
				return "error:" + e.Message;
			}
		}

	}
}
